package edu.pucsp.predatorprey.tela;

import java.util.Map;

import edu.pucsp.predatorprey.simulador.impl.InformacaoCiclo;
import edu.pucsp.predatorprey.simulador.java.criatura.AbstractCriatura;
import edu.pucsp.predatorprey.simulador.java.posicao.impl.Posicao;
import edu.pucsp.predatorprey.simulador.java.terreno.impl.TerrenoImpl;
import edu.pucsp.predatorprey.tela.observer.Observavel;
import edu.pucsp.predatorprey.tela.util.CicloDeVida;

public class Modelo extends Observavel {

	private int qtdPresas;

	private int qtdPredadores;

	private int numeroDeExecucoesSimultaneas;

	private AbstractCriatura[][] posicaoCriaturas = new AbstractCriatura[TerrenoImpl.WIDTH][TerrenoImpl.HEIGHT];

	private PosicaoListener listener;

	private int ciclos;

	public void definirPosicaoCriaturas(Map<AbstractCriatura, Posicao> posicaoCriaturas) {
		for (AbstractCriatura criatura : posicaoCriaturas.keySet()) {
			Posicao posicao = posicaoCriaturas.get(criatura);
			this.posicaoCriaturas[posicao.getX()][posicao.getY()] = criatura;
		}
		this.notificarObservadores(CicloDeVida.COMECOU);
	}

	public int getQtdPresas() {
		return this.qtdPresas;
	}

	public int getQtdPredadores() {
		return this.qtdPredadores;
	}

	public int getNumeroDeExecucoesSimultaneas() {
		return this.numeroDeExecucoesSimultaneas;
	}

	public AbstractCriatura[][] getPosicaoCriaturas() {
		return this.posicaoCriaturas;
	}

	public void criaturaMorreu(Posicao posicao) {
		this.posicaoCriaturas[posicao.getX()][posicao.getY()] = null;
		this.listener.mudouPosicao(posicao);
	}

	public void criaturaNasceu(AbstractCriatura criatura, Posicao posicao) {
		this.posicaoCriaturas[posicao.getX()][posicao.getY()] = criatura;
		this.listener.mudouPosicao(posicao);
	}

	public void criaturaMoveu(Posicao origem, Posicao destino) {
		AbstractCriatura criatura = this.posicaoCriaturas[origem.getX()][origem.getY()];
		this.posicaoCriaturas[origem.getX()][origem.getY()] = null;
		this.posicaoCriaturas[destino.getX()][destino.getY()] = criatura;
		this.listener.mudouPosicao(origem);
		this.listener.mudouPosicao(destino);
	}

	public void setPosicaoListener(PosicaoListener listener) {
		this.listener = listener;
	}

	public void cicloCompleto(InformacaoCiclo informacao) {
		this.qtdPresas = informacao.getNumeroPresas();
		this.qtdPredadores = informacao.getNumeroPredadores();
		this.ciclos = informacao.getCiclo();
		this.notificarObservadores(CicloDeVida.EXECUTANDO);
	}

	public void simulacaoParou() {
		this.posicaoCriaturas = new AbstractCriatura[TerrenoImpl.WIDTH][TerrenoImpl.HEIGHT];
		this.notificarObservadores(CicloDeVida.PAROU);
	}

	public int getCiclos() {
		return this.ciclos;
	}

	public void numeroDeExecucoesSimultaneas(int execucoes) {
		this.numeroDeExecucoesSimultaneas = execucoes;
	}

}
